using GameBaseFramework.Base;
using GameBaseFramework.Extension;
using GameBaseFramework.FrameWorkCommand;
using GameBaseFramework.Network;
using GameBaseFramework.Pattern;
using System.Collections;
using System.Collections.Generic;
using Bright.Serialization;
using GameGraphics;
using GameLogics;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

/// <summary>
/// 加载分步信息
/// </summary>
public class LoadingStepInfo
{
    /// <summary>
    /// 每一分步的提示信息
    /// </summary>
    public string Tips;
    /// <summary>
    /// 每一分步的占比（百分制计）
    /// </summary>
    public float Ratio;
    /// <summary>
    /// 协程
    /// </summary>
    public IEnumerator<float> Routine;
}


/// <summary>
/// 游戏入口
/// </summary>
public class GameLauncher : MonoBehaviour, Icommand
{
    // Start is called before the first frame update
    void Start()
    {
        MainLogic.Init();
        DebugTool.Init(new UnityDebugConsole());
        DebugTool.EnableLog = true;
        DebugTool.Log("Unity Game Start");
        StartLoad();
        //NetworkManager.Instance.ConnectServer(NetworksConfig.IP, NetworksConfig.port);
    }

    /// <summary>
    /// 真实的进度
    /// </summary>
    private float _loadProgress = 0f;
    /// <summary>
    /// 表现进度条
    /// </summary>
    private float _displayProgress = 0f;
    private float displayProgress
    {
        get
        {
            return _displayProgress;
        }
        set
        {
            _displayProgress = Mathf.Min(1.0f, value);
        }
    }

    /// <summary>
    /// 初始化
    /// </summary>
    private void Awake()
    {
        Application.targetFrameRate = 60;
    }

    /// <summary>
    /// 开始加载
    /// </summary>
    private void StartLoad()
    {
        var list = new List<LoadingStepInfo>();
        var loadTableStep = new LoadingStepInfo();
        loadTableStep.Tips = "加载表格资源...";
        loadTableStep.Ratio = 0.5f;
        loadTableStep.Routine = LoadTables();
        list.Add(loadTableStep);

        var loadUIPrefabStep = new LoadingStepInfo();
        loadUIPrefabStep.Tips = "初始化配置...";
        loadUIPrefabStep.Ratio = 0.5f;
        loadUIPrefabStep.Routine = Initialize();
        list.Add(loadUIPrefabStep);

        //var loadAssetStep = new LoadingStepInfo();
        //loadAssetStep.Tips = "加载模型资源...";
        //loadAssetStep.Ratio = 0.45f;
        //loadAssetStep.Routine = LoadModels();
        //list.Add(loadAssetStep);

        StartCoroutine(Load(list));
    }

    /// <summary>
    /// 初始化
    /// </summary>
    /// <returns></returns>
    private IEnumerator<float> Initialize()
    {
        //音频播放器
        while (false)
        {
            yield return 1.0f;
        }
        Debug.Log("游戏逻辑加载完成");
    }

    /// <summary>
    /// 开始加载
    /// </summary>
    /// <returns></returns>
    private IEnumerator<float> LoadTables()
    {
        var tableDataDict = new Dictionary<string, TextAsset>();
        System.Func<string, ByteBuf> loader = (file) =>
        {
            return new ByteBuf(tableDataDict[file].bytes);
        };
        var loadTableDatasHandle = Addressables.LoadAssetsAsync<TextAsset>("TableData", null);

        while (!loadTableDatasHandle.IsDone)
        {
            yield return loadTableDatasHandle.PercentComplete;
        }
        if (loadTableDatasHandle.Status == AsyncOperationStatus.Succeeded)
        {
            Debug.Log($"loadTableDatasHandle.Status: {loadTableDatasHandle.Status}");
            var tableDatas = loadTableDatasHandle.Result;
            foreach (var textAsset in tableDatas)
            {
                tableDataDict.Add(textAsset.name, textAsset);
            }
        }
        MainLogic.Tables = new cfg.Tables(new(loader));
        yield return 1.0f;
        DebugTool.Log("表格加载完成");
    }

    /// <summary>
    /// 开始加载
    /// </summary>
    private IEnumerator Load(List<LoadingStepInfo> list)
    {
        for (var i = 0; i < list.Count; i++)
        {
            var info = list[i];
            //TextTips.text = info.Tips;
            while (info.Routine.MoveNext())
            {
                var cur = info.Ratio * info.Routine.Current;
                while (_displayProgress < cur + _loadProgress)
                {
                    displayProgress += 0.01f;
                    yield return null;
                }
                yield return null;
            }
            _loadProgress += info.Ratio;
        }
        displayProgress = 1.0f;
        var obj = new GameObject();
        MainGraphic.GameManager = obj.AddComponent<GameManager>();
        yield return new WaitForEndOfFrame();
        Destroy(this);
    }
}
